"""
项目说明详见README.MD
代码注释比较详细，请参考。
"""

import re
import json
import time



# 去除字符串中某种的字符的举例
#s = '\tabc\t123\tisk'
#print(s.replace('\t', '')) # 去除'\t'字符语法

def remove_char(re,s):
    # 去除re指定的字符，re举例“\r\n\t”
    #s = '\r\nabc\t123\nxyz'
    #print(re.sub('[\r\n\t]', '', s)) # re是正则表达式，比如'[\r\n\t]'
    return re.sub(re, '',s)

def get_field(obj,key):
    #从json某层对象object中获取健值key指定的值value
    try:
        tmp_str =""
        tmp_str = obj[key]
    except :
        # print("[WARN]健值key[{0}]不存在于对象中,默认赋值为空字符串！".format(key))
        pass
    finally:
        return tmp_str

def get_yyyymmdd():
    #返回时间字符串，举例：“20180101”
    return time.strftime('%Y%m%d',time.localtime(time.time()))

def get_yyyy_mm_dd():
    # 返回时间字符串，举例：“2018-01-01”
    return time.strftime('%Y-%m-%d',time.localtime(time.time()))

def rn(f):
    f.write("\n") #换行小函数；如果"\r\n"就会引起换2行！

def clear(str):
    #去除不需要的字符，用来清洗字符串。
    s = str
    str.replace(" ","") #清除空格
    #str.replace("\t", "") #清除\t
    re.sub('[\t*]', '', str)
    return s

'''
将由中英文的句号和逗号分隔的一行长字符串(比如一句长诗),
按句号或逗号自然分为多行，保留句号逗号！且不超过宽度width设定值!
例外：当连续没逗号句号分隔的超过width的句子，则不做文字分割！
'''
def split_line(one_line, width):
    #算法：
    # 1.将1行长字符串用中英文句号逗号split为list；
    # 2.对list按照width设定，增加尾部换行符\n；
    # 3.处理list并写入输出文件的地方，根据\n来处理换行，达到目的.
    one_line = clear(one_line) #去除空格等
    one_line = one_line.replace("，","， ") #为英文逗号增加空格，便于split默认用空格分隔，下同！
    one_line = one_line.replace("。","。 ")
    one_line = one_line.replace(",",", ")
    one_line = one_line.replace(".",". ")
    list = one_line.split() #分割为多行的list
    # 按照width列宽限制来进一步处理，添加合适的换行\n
    return auto_newline_limit_wide(list, width)

def auto_newline_limit_wide(onelist, width):
    # 按照width列宽限制来进一步处理，添加合适的换行\n
    list=onelist
    # 算法：将list元素(代表每行)拼接；if 长度>width，则对[前一行]尾部插入一个\n
    tmp_line = ""
    for i in range(len(list)):
        line = list[i]
        tmp_line = tmp_line+line
        if len(tmp_line)> width:
            tmp_line = line #重新再计算长度，当前line作为第一个元素等待拼接并等待下一次判断长度是否超限width
            list[i-1] = list[i-1]+"\n" #当前line上一行(list的上个元素)尾部添加一个\n
    return list

def tail_has_rn(str):
    #判断最后一个字符是不是\n换行符
    if str[-1]=='\n':
        return True
    else:
        return False

'''
调整字段格式，并输出为post新文件
'''
def gen_post(f,title,author,topic,dynasty,detail_text,
             detail_translate_list, detail_appreciation_list,detail_background_list):
    # 准备其他字段
    yyyymmdd = get_yyyymmdd() #准备日期，自动生成post用，下同
    yyyy_mm_dd = get_yyyy_mm_dd() #准备日期
    poem_prefix = ">### " #诗歌名称前缀
    famous_sentence_prefix = ">### " # 名句前缀（可能用不到，因为JSON数据当中无名句）
    detail_translate_prefix = ">#### " #其他附加字段前缀，下同
    detail_appreciation_prefix = ">#### "
    detail_background_prefix = ">#### "

    # 生成post的header小结，格式详见模板post“yyyy-mm-dd-template.md”(符合jekyll的post格式)，说明：
    # 原本期望用文本文件模板，填充模板字段的方式来生成POST，
    # 无奈，因为一下子找不到python3合适的文本模板填充类库，
    # 所以改为直接生成每一行数据并写入post文件的方式，所以模板也沦为了只是coding时候的参考而已！
    f.write('---') ; rn(f)
    f.write('layout: post'); rn(f)
    f.write('title: '+yyyymmdd+" - 《"+title+"》"+author); rn(f)
    f.write('key: '+yyyymmdd); rn(f)
    f.write('tags: '+ author +" "+topic+" "+dynasty); rn(f)
    f.write('modify_date: '+yyyy_mm_dd); rn(f)
    f.write('---'); rn(f)
    f.write('```'); rn(f)
    f.write('正文'); rn(f)
    f.write('```'); rn(f)

    # 生成post的poem正文诗歌主体小结
    f.write(poem_prefix+"《"+title+"》"+author); rn(f)
    #将detail_text字段处理并拆分为限宽width的多行.
    detail_text_list=split_line(detail_text,10)
    next_need_prefix = True
    for line in detail_text_list:
        #f.write(poem_prefix+clear(line))#; rn(f)
        if next_need_prefix:
            f.write(poem_prefix + clear(line))
        else:
            f.write(clear(line))
        if tail_has_rn(line):
            next_need_prefix = True  # 根据上一行尾部有换行，则置位true，新行需要前缀prefix，否则为false，下同！
        else:
            next_need_prefix = False

    rn(f)
    
    # 生成post的名句小结，此小节因为json数据源没有此字段，而暂时留空
    #rn(f)
    #f.write('```'); rn(f)
    #f.write('名句'); rn(f)
    #f.write('```'); rn(f)
    #f.write(famous_sentence_prefix+" 略"); rn(f) #暂时为空

    # 生成post的译文及注释小结
    # 此小节json数据源本来就是换行多行，所以不用额外处理
    f.write('```'); rn(f)
    f.write('译文及注释'); rn(f)
    f.write('```'); rn(f)
    for line in detail_translate_list:
        f.write(detail_translate_prefix+clear(line));rn(f)

    # 生成post的鉴赏小结
    f.write('```'); rn(f)
    f.write('鉴赏'); rn(f)
    f.write('```'); rn(f)
    next_need_prefix = True
    for line in detail_appreciation_list:
        list = split_line(line,20) #对此小节原本非常行的多行数据，每一行再进行一次限宽分行处理
        for line2 in list:
            if next_need_prefix:
                f.write(detail_appreciation_prefix + clear(line2))
            else:
                f.write(clear(line2))
            if tail_has_rn(line2):
                next_need_prefix = True #根据上一行尾部有换行，则置位true，新行需要前缀prefix，否则为false，下同！
            else:
                next_need_prefix = False
        rn(f)


    # 生成post的背景小结
    f.write('```'); rn(f)
    f.write('背景'); rn(f)
    f.write('```'); rn(f)
    next_need_prefix = True
    for line in detail_background_list:
        list = split_line(line,20) #对此小节原本非常行的多行数据，每一行再进行一次限宽分行处理
        for line2 in list:
            if next_need_prefix:
                f.write(detail_background_prefix + clear(line2))
            else:
                f.write(clear(line2))
            if tail_has_rn(line2):
                next_need_prefix = True
            else:
                next_need_prefix = False
        rn(f)

    f.flush()  # 把缓冲区的内容写入硬盘

'''
MAIN PROCEDURE IN MODULE !!!
'''
jsonfile_tangshi_300 = '../json/tangshi_300.json' #定义json数据源文件
jsonfile_tangshi_test = '../json/tangshi_2.json' #用来测试的小数据json文件
jsonfile = jsonfile_tangshi_300
gen_path = '../post/' #生成的post文件的指定目录

# 解析json数据源并生成post
with open(jsonfile, 'r',encoding="UTF-8") as j:
    o = json.load(j)
    #print("len(o)={0}".format(len(o)))
    father_idx = 0
    gen_post_succ_count = 0; gen_post_fail_count = 0
    # 解析json文件，详见json文件格式举例：“tangshi_2.json”!
    while (father_idx<len(o['father'])) :
        # if father[x] EXIST, goon
        father = o['father'][father_idx] #获得father节点
        topic = (father['topic']).replace('：','') #获得father[x]的唯一子topic节点
        des = father['des'] #获得father[x]的唯一子des节点
        des_idx = 0
        while (des_idx<len(des)): #des里面有多首诗歌的数组
            #if des[x] EXIST, parse ONE POEM!
            p = des[des_idx]
            title = get_field(p, 'title').replace('·', ' ').strip() #解析获取并处理诗歌名
            author = get_field(p, 'detail_author') #解析并获取作者
            if len(author)>0:
                author = author[0] #不支持多个作者！
            else:
                author = "未知"

            dynasty = get_field(p, 'detail_dynasty') #解析获取并处理朝代
            detail_text = get_field(p, 'detail_text') #解析获取并处理诗歌正文
            detail_translate_list = get_field(p, 'detail_translate_text') #解析获取并处理诗歌解析
            detail_appreciation_list = get_field(p, 'detail_appreciation_text') #解析获取并处理诗歌赏析
            detail_background_list = get_field(p, 'detail_background_text')#解析获取并处理诗歌背景

            # 如下仅供DEBUG时打印信息用
            #print("topic=[{0}],auther=[{1}],title=[{2}]，dynasty=[{3}]".format(topic, author,title,dynasty))
            #print("detail_text=[{0}]".format(detail_text))
            #print("detail_translate=[{0}]".format(detail_translate_list))
            #print("detail_appreciation=[{0}]".format(detail_appreciation_list))
            #print("detail_background=[{0}]".format(detail_background_list))

            #生成post(不是读入模板替换，而是从全新文件依照模板样子一行行生成！）
            post_filename = get_yyyy_mm_dd()+"-"+title.replace(' ','-')+"-"+author+".md" #post新文件名称
            index_filename = "post_index.md" #因为生成了数百个post，需要一个md格式的index，供编目用！
            f = open(gen_path + post_filename, 'w',encoding="UTF-8") #读写方式打开文件，不存在则创建，非追加模式。
            f2 = open(gen_path + index_filename, 'a', encoding="UTF-8")  # 读写方式打开文件，不存在则创建，追加模式。
            try:
                gen_post(f,title,author,topic,dynasty,detail_text,
                     detail_translate_list,detail_appreciation_list,detail_background_list)
                #print("[DEBUG]诗歌[{0}]生成post文件成功！".format(title))
                gen_post_succ_count = gen_post_succ_count+1
                # index文件举例如下：
                # “><br>[20180112-《送杜少府之任蜀州》王勃](./_posts/2018-01-12-送杜少府之任蜀州-王勃.md)”
                f2.write("><br>["+post_filename+"](./_posts/"+post_filename+")");rn(f2)
            except :
                pass
                print("[WARN]诗歌[{0}]生成post文件失败！".format(title))
                gen_post_fail_count  = gen_post_fail_count +1
                raise
            finally:
                f.close()
                f2.close()





            des_idx = des_idx+1 # get next poem

        # get next topic
        father_idx = father_idx +1  #get next topic/des
        print("[INFO]统计：topic[{0}]发现诗篇[{1}]首.".format(topic,des_idx))
    print("[INFO]统计：成功转换为POST[{0}]篇，失败[{1}]".format(gen_post_succ_count, gen_post_fail_count))

